package com.biz.primus.ms.thirdlogin.service;

import com.biz.primus.base.enums.ChannelTypes;
import com.biz.primus.base.exception.BizBusinessException;
import com.biz.primus.model.thirdlogin.enums.OAuthTypes;
import com.biz.primus.model.thirdlogin.vo.OAuthMemberVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.thirdlogin.dao.po.OAuthMember;
import com.biz.primus.ms.thirdlogin.dao.repository.OAuthMemberRepository;
import com.biz.primus.ms.thirdlogin.oauth.service.CustomOAuthService;
import com.biz.primus.ms.thirdlogin.oauth.service.OAuthServices;
import com.biz.primus.ms.thirdlogin.trans.OAuthMemberToOAuthMemberVo;
import lombok.extern.slf4j.Slf4j;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * @author jun.liu
 * @date 2017/9/29
 */
@Slf4j
@Service
public class ThirdloginService extends AbstractBaseService
{

    private final OAuthMemberRepository oAuthMemberRepository;
    private final OAuthServices oAuthServices;

    @Autowired
    public ThirdloginService(OAuthMemberRepository oAuthMemberRepository, OAuthServices oAuthServices)
    {
        this.oAuthMemberRepository = oAuthMemberRepository;
        this.oAuthServices = oAuthServices;
    }

    public OAuthMemberVo queryOAuthMemberByOAuthId(OAuthTypes oAuthType, String oAuthId)
    {
        Optional<OAuthMember> oAuthMember = Optional.ofNullable(oAuthMemberRepository.findByOAuthTypeAndOAuthId(oAuthType, oAuthId));
        //如果查询本地系统关系绑定为null 证明本地关系未绑定 返回null给调用者 调用者监听到是null 则跳转到绑定页面进行绑定
        //如果查询本地系统关系绑定不为null 证明本地关系已绑定 返回查询到的对象给调用者 调用者监听到不是null 则跳转到正常逻辑流程
        if (oAuthMember.isPresent()) {
            return new OAuthMemberToOAuthMemberVo().apply(oAuthMember.get());
        }
        throw new BizBusinessException("OAuthMemberVo query is null by OAuthTypes and oAuthId");
    }

    public OAuthMemberVo queryOAuthMemberByAccessToken(OAuthTypes oAuthType, String code)
    {
        Optional<CustomOAuthService> oAuthService = Optional.ofNullable(oAuthServices.getOAuthService(oAuthType.name()));
        if(oAuthService.isPresent())
        {
            Token accessToken = oAuthService.get().getAccessToken(null, new Verifier(code));
            OAuthMember accessTokenOAuthMember = oAuthService.get().getOAuthMember(accessToken);
            return new OAuthMemberToOAuthMemberVo().apply(accessTokenOAuthMember);
        }
        throw new BizBusinessException("The developer account is not configured");
    }

    public OAuthMemberVo binding(OAuthTypes oAuthType, ChannelTypes channelType, String oAuthId, Long memberId)
    {
        OAuthMember oAuthMember = new OAuthMember();
        oAuthMember.setOAuthId(oAuthId);
        oAuthMember.setOAuthType(oAuthType);
        oAuthMember.setChannelType(channelType);
        oAuthMember.setMemberId(memberId);
        oAuthMember = oAuthMemberRepository.save(oAuthMember);
        return new OAuthMemberToOAuthMemberVo().apply(oAuthMember);
    }

    public void unBinding(OAuthTypes oAuthType, String oAuthId, Long memberId)
    {
        Optional<OAuthMember> oAuthMember = Optional.ofNullable(oAuthMemberRepository.findByOAuthTypeAndOAuthIdAndMemberId(oAuthType, oAuthId, memberId));
        if (oAuthMember.isPresent()) {
            oAuthMemberRepository.delete(oAuthMember.get());
        }
        throw new BizBusinessException("OAuthMember query is null");
    }

    public void unBinding(OAuthTypes oAuthType, String oAuthId)
    {
        Optional<OAuthMember> oAuthMember = Optional.ofNullable(oAuthMemberRepository.findByOAuthTypeAndOAuthId(oAuthType, oAuthId));
        if (oAuthMember.isPresent()) {
            oAuthMemberRepository.delete(oAuthMember.get());
        }
        throw new BizBusinessException("OAuthMember query is null");
    }

}
